package com.lengxf.netty.config.handler;

import cn.hutool.json.JSONUtil;
import com.lengxf.netty.command.Command;
import com.lengxf.netty.command.CommandFactory;
import com.lengxf.netty.config.ChannelContext;
import com.lengxf.netty.config.message.NettyMessage;
import com.lengxf.netty.enums.OperateTypeEnum;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.ReferenceCountUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

@Slf4j
@Component
@AllArgsConstructor
@ChannelHandler.Sharable
public class UserWebSocketFrameHandler extends ChannelInboundHandlerAdapter {


    private final CommandFactory commandFactory;

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        if (msg instanceof TextWebSocketFrame textWebSocketFrame) {
            handleTextWebSocketFrame(ctx, textWebSocketFrame);
            ReferenceCountUtil.release(msg);
        }

        super.channelRead(ctx, msg);
    }

    private void handleTextWebSocketFrame(ChannelHandlerContext ctx, TextWebSocketFrame textWebSocketFrame) {
        log.info("接收到消息：{}", textWebSocketFrame.text());
        String text = textWebSocketFrame.text();
        NettyMessage message = JSONUtil.toBean(text, NettyMessage.class);
        OperateTypeEnum command = OperateTypeEnum.getEnumByCode(message.getMessageType());
        Command interaction = commandFactory.getImpl(command);
        interaction.handle(ctx.channel(), message.getText());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
//        ctx.close();
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("链接创建({})-remoteAddress:({})...", ctx.channel().id().asLongText(), ctx.channel().remoteAddress());
        ChannelContext.saveChannel(ctx.channel().id().asLongText(), ctx.channel());
        super.channelActive(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("链接({})断开..", ctx.channel().id().asLongText());
        ChannelContext.removeChannel(ctx.channel().id().asLongText());
        super.channelInactive(ctx);
    }


}
